package bb.lanxing.lib.devices.base;

import java.util.ArrayList;
import java.util.List;

import org.litepal.LitePal;

import android.content.ContentValues;
import android.content.Context;
import android.os.Parcel;
import android.util.Log;

import bb.lanxing.lib.devices.api.DeviceManager;
import bb.lanxing.lib.devices.api.DeviceProvider;
import bb.lanxing.lib.devices.api.SmartDevice;
import bb.lanxing.lib.devices.common.DeviceLogger;
import bb.lanxing.lib.devices.remote.IRemoteDeviceService;
import bb.lanxing.model.database.Device;


public class DeviceContext {
    final private static String TAG = "DeviceContext";
    private static DeviceContext INSTANCE;
    private static List<Runnable> initTasks;
    private Context mAppContext;
    private DeviceConfiguration mConfiguration;
    private DeviceLogger mDeviceLogger;
    private DeviceProvider mDeviceProvider;
    private DeviceServiceBinder mDeviceServiceBinder;

    private static AutoConnectorJava threadAutoConnector = null;

    private DeviceContext(Context context) {
        this.mAppContext = context;
    }

    public static DeviceContext init(Context context) {
        synchronized (DeviceContext.class) {
            DeviceContext deviceContext = INSTANCE;
            if (deviceContext != null) {
                return deviceContext;
            }
            DeviceContext deviceContext2 = new DeviceContext(context);
            INSTANCE = deviceContext2;
            return deviceContext2;
        }
    }

    public static void onReady(Context context) {
        synchronized (DeviceContext.class) {
            DeviceContext deviceContext = INSTANCE;
            if (deviceContext == null) {
                return;
            }
            if (deviceContext.mAppContext == null) {
                deviceContext.mAppContext = context.getApplicationContext();
            }
            DeviceServiceBinder deviceServiceBinder = getDeviceServiceBinder();
            if (deviceServiceBinder != null) {
                deviceServiceBinder.bindDeviceService(context);
            }
        }
    }

    public static DeviceContext getInstance() {
        return INSTANCE;
    }

    public static void release() {
        synchronized (DeviceContext.class) {
            DeviceContext deviceContext = INSTANCE;
            if (deviceContext != null && deviceContext.mAppContext != null) {
                DeviceManager deviceManager = getDeviceManager();
                if (deviceManager != null) {
                    deviceManager.release();
                }
                DeviceContext deviceContext2 = INSTANCE;
                DeviceServiceBinder deviceServiceBinder = deviceContext2.mDeviceServiceBinder;
                if (deviceServiceBinder != null) {
                    deviceServiceBinder.unbindDeviceService(deviceContext2.mAppContext);
                }
                List<Runnable> list = initTasks;
                if (list != null) {
                    list.clear();
                    initTasks = null;
                }
                DeviceContext deviceContext3 = INSTANCE;
                deviceContext3.mAppContext = null;
                deviceContext3.mConfiguration = null;
//                deviceContext3.mBiciBinder = null;
                deviceContext3.mDeviceLogger = null;
                deviceContext3.mDeviceProvider = null;
                deviceContext3.mDeviceServiceBinder = null;
                INSTANCE = null;
            }
        }
    }

    public static boolean isReleased() {
        boolean z;
        synchronized (DeviceContext.class) {
            z = INSTANCE == null;
        }
        return z;
    }

    public DeviceContext setDeviceConfiguration(DeviceConfiguration deviceConfiguration) {
        this.mConfiguration = deviceConfiguration;
        return this;
    }

    public DeviceContext setDeviceLogger(DeviceLogger deviceLogger) {
        this.mDeviceLogger = deviceLogger;
        return this;
    }

    public DeviceContext setDeviceProvider(DeviceProvider deviceProvider) {
        this.mDeviceProvider = deviceProvider;
        return this;
    }

    public DeviceContext setDeviceServiceBinder(DeviceServiceBinder deviceServiceBinder) {
        if (mDeviceServiceBinder != null) {
            mDeviceServiceBinder.unbindDeviceService(this.mAppContext);
        }
        mDeviceServiceBinder = deviceServiceBinder;
        return this;
    }

    public static DeviceManager getDeviceManager() {
        if (isReleased()) {
            return null;
        }
        LocalDeviceManager.init();
        return LocalDeviceManager.getInstance();
    }

    public IRemoteDeviceService getRemoteDeviceService() {
        if (mDeviceServiceBinder != null) {
            return mDeviceServiceBinder.getDeviceService();
        }
        return null;
    }

    public static DeviceConfiguration getDeviceConfiguration() {
        return INSTANCE.mConfiguration;
    }

    public static DeviceProvider getDeviceProvider() {
        DeviceContext deviceContext = INSTANCE;
        if (deviceContext == null) {
            Log.e(TAG, "INSTANCE == null");
            return null;
        }
        DeviceProvider deviceProvider = deviceContext.mDeviceProvider;
        if (deviceProvider == null) {
            Log.e(TAG, "INSTANCE.mDeviceProvider == null");
            return null;
        }
        return deviceProvider;
    }

    public static DeviceLogger getDeviceLogger() {
        return INSTANCE.mDeviceLogger;
    }

//    public static BiciBinder getBiciBinder() {
//        return INSTANCE.mBiciBinder;
//    }

    public static DeviceServiceBinder getDeviceServiceBinder() {
        return INSTANCE.mDeviceServiceBinder;
    }

    public static void addBindTask(Runnable runnable) {
        DeviceContext deviceContext = INSTANCE;
        if (deviceContext == null || deviceContext.mDeviceServiceBinder == null) {
            if (initTasks == null) {
                initTasks = new ArrayList();
            }
            initTasks.add(runnable);
            return;
        }
        List<Runnable> list = initTasks;
        if (list != null) {
            for (Runnable runnable2 : list) {
                INSTANCE.mDeviceServiceBinder.addBindTask(runnable2);
            }
            initTasks.clear();
            initTasks = null;
        }
        INSTANCE.mDeviceServiceBinder.addBindTask(runnable);
    }

    public static String getRootDir(int i) {
        return INSTANCE.mConfiguration.getRootDir(i);
    }

    public static List<SmartDevice> getDevicesByType(int i) {
        return getDeviceProvider().getDevicesByType(i);
    }

    public static SmartDevice getDeviceByType(int i) {
        List<SmartDevice> devicesByType = getDevicesByType(i);
        if (devicesByType == null || devicesByType.isEmpty()) {
            return null;
        }
        return devicesByType.get(0);
    }

    public static SmartDevice getDeviceByAddress(String str) {
        return getDeviceProvider().getDeviceByAddress(str);
    }

    public static void save(SmartDevice smartDevice) {
//        getDeviceProvider().save(smartDevice);
        boolean needAutoConnect = Device.isThisTypeNeedAutoConnect(smartDevice.getType());
        if (needAutoConnect && (smartDevice instanceof Device)) {
            String address = smartDevice.getAddress();
            Device existDevice = Device.getByAddress(address);
            Log.d(TAG, "save: address=" + address + ", existDevice=" + existDevice);
            if (existDevice != null) {
                Log.d(TAG, "save: existDevice id=" + existDevice.getId()
                        + ",flags=" + existDevice.getFlags() + ", new flags=" + smartDevice.getFlags());
                ContentValues contentValues = new ContentValues();
                contentValues.put("flags", smartDevice.getFlags());
                LitePal.update(Device.class, contentValues, existDevice.getId());
            } else {
                Log.d(TAG, "save: save directly.");
                getDeviceProvider().save(smartDevice);
            }
        }

    }

    public static void saveDeviceVersion(String address, String version) {
        Device existDevice = Device.getByAddress(address);
        Log.d(TAG, "save: address=" + address + ", existDevice=" + existDevice);
        if (existDevice != null) {
            ContentValues contentValues = new ContentValues();
            contentValues.put("devicefwdisplayversion", version);
            LitePal.update(Device.class, contentValues, existDevice.getId());
        }
    }

    public static SmartDevice createDeviceFromByteArray(byte[] bArr) {
        if (bArr == null) {
            return null;
        }
        Parcel obtain = Parcel.obtain();
        obtain.unmarshall(bArr, 0, bArr.length);
        obtain.setDataPosition(0);
        SmartDevice create = getDeviceProvider().create();
        if (create != null) {
            create.readFromParcel(obtain);
        }
        obtain.recycle();
        return create;
    }

    public static SmartDevice createDevice() {
        return getDeviceProvider().create();
    }

    public static byte[] createByteArrayFromDevice(SmartDevice smartDevice) {
        Parcel obtain = Parcel.obtain();
        smartDevice.writeToParcel(obtain, 0);
        byte[] marshall = obtain.marshall();
        obtain.recycle();
        return marshall;
    }

    public static List<SmartDevice> getDevices() {
        return getDeviceProvider().getDevices();
    }

    public static boolean isSecondGenerationDevice(int i) {
        return getDeviceProvider().isSecondGenerationDevice(i);
    }

    public static boolean isSensorDevice(int i) {
        return getDeviceProvider().isSensorDevice(i);
    }

    public static boolean isNeedAutoConnectDeviceType(int i) {
        return getDeviceProvider().isAutoConnectDeviceType(i);
    }

    public static Context getApplicationContext() {
        if (isReleased()) {
            return null;
        }
        return INSTANCE.mAppContext;
    }

    public static boolean isAntPlusEnabled() {
        return !isReleased() && INSTANCE.mConfiguration.isAntPlusEnabled();
    }

    public static boolean isBiciDebuggable() {
        return !isReleased() && INSTANCE.mConfiguration.isBiciDebuggable();
    }

    public static void startAndRefreshAutoConnector() {
        Log.d(TAG, "startAndRefreshAutoConnector...");
//        AutoConnector.Companion.getInstance().startOrRefresh();
        if (getDeviceProvider() == null) {
            return;
        }
        DeviceManager deviceManager = getDeviceManager();
        List<SmartDevice> list = getDevices();
        if (deviceManager != null && list != null && !list.isEmpty()) {
            threadAutoConnector = new AutoConnectorJava((AbstractXZDeviceManager) deviceManager, list);
            threadAutoConnector.start();
        }
    }

    public static void stopAutoConnector() {
        Log.d(TAG, "stopAutoConnector...");
//        AutoConnector.Companion.getInstance().stop();
        if (threadAutoConnector != null) {
            threadAutoConnector.quit();
        }

    }
}
